import requests
from bs4 import BeautifulSoup
import bs4
import re
import traceback
import json
from collections import namedtuple
import os

code_map = {}
st_info_file = "st_info.txt"

kv = {
    'User-agent' : 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
}

def get_st_info_from_file():
    st_info_map = {}
    if os.path.exists(st_info_file):
        with open(st_info_file, "r") as f:
            for line in f:
                code, code_json = line.strip().split("\t")
                st_info_map[code] = json.loads(code_json)
    return st_info_map

def write_st_info_to_file(stmap):
    print(stmap)
    st_info_map = {}
    with open(st_info_file, "w") as f:
        for key, value in stmap.items():
            f.write(key + "\t" + json.dumps(value) + "\n")



code_map = get_st_info_from_file()




def get_content(code):
    try:
        BASE_INFO_URL = "https://www.futunn.com/stock/{ST_CODE}"
        url = BASE_INFO_URL.format(ST_CODE = code)
        r = requests.get(url,headers = kv)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        str1 = r.text.replace('\ufffd','').replace('\u30fb','').replace('\xa0','').replace('\xa9','')
        return str1
    except:
        return 'st fail'

def get_st_info(code):
    if code in code_map:
        st_info = code_map[code]
        return st_info
    content = get_content(code)
    PARTTEN = r'"stockInfo"\s*:\s*(\{[^}]+\})'
    pre = re.compile(PARTTEN)
    res = pre.search(content)
    nn_st_info = None
    if res:
        stinfo = json.loads(res.groups()[0])
        src_code = stinfo['src_code']
        name = stinfo['name']
        nn_st_id = stinfo['stock_id']
        nn_st_info = {"code": src_code, "name": name, "nn_st_id": nn_st_id}
    code_map[code] = nn_st_info
    write_st_info_to_file(code_map)
    return nn_st_info


"""
https://www.futunn.com/quote-api/get-kline?stock_id=78224239372036&market_type=1&type=2
type:
    2 day
    3 week
    4 month
    11 season
    5 year
"""
def get_freq_kline(code, freq = "d"):
    code_info = get_st_info(code)
    if not code_info:
        return None
    code_id = code_info['nn_st_id']
    freq_type = 2
    if freq == "d":
        freq_type = 2
    elif freq == "w":
        freq_type = 3
    elif freq == "m":
        freq_type = 4
    elif freq == "s":
        freq_type = 11
    elif freq == "y":
        freq_type = 5

    rt_url = "https://www.futunn.com/quote-api/get-kline?stock_id={ST_ID}&market_type=1&type={FREQ_TYPE}".format(ST_ID = code_id, FREQ_TYPE = freq_type)
    res = requests.get(rt_url, headers = kv)
    info = json.loads(res.text)
    return info

"""
https://www.futunn.com/quote-api/get-quote-minute?stock_id=76033806042898&market_type=1&type=1
type=1 today
type=2 5day
"""
def get_realtime_st(code):
    code_info = get_st_info(code)
    if not code_info:
        return None
    code_id = code_info['nn_st_id']
    rt_url = "https://www.futunn.com/quote-api/get-quote-minute?stock_id={ST_ID}&market_type=1&type=1".format(ST_ID = code_id)
    res = requests.get(rt_url, headers = kv)
    scode = res.status_code

    if scode != 200:
        return None
    info = json.loads(res.text)
    code = info['code']
    if code != 0:
        print(code['message'])
        return None
    data = info['data']
    last_close = data['last_close_price']/1000
    latest = data['list'][-1]
    latest_price = latest['price']/1000
    ratio = latest['ratio']
    return (code_info['name'], code_info['code'], last_close, latest_price, ratio)



